import { Button, Card, Form, Input, message, Select, Table, Tag } from 'antd'
import { PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import React, { useEffect, useState } from 'react'
import { removeAttr, reqAddOrUpDate, reqCategory1List, reqCategory2List, reqCategory3List, reqGetAttrList } from '@/api/category';
import { AttrItem, AttrList, AttrValueItem, AttrValueList, category1Item, category1List, category2Item, category2List, category3Item, category3List } from '@/api/category/model/categoryType';
import { ColumnsType } from 'antd/lib/table';
import FormItem from 'antd/lib/form/FormItem';
import { attachTypeApi } from 'antd/lib/message';
import { cloneDeep } from 'lodash'




export default function HospitalList() {

  const [category1Id, setCategory1Id] = useState<number>()
  const [categoryOneList, setCategoryOneList] = useState<category1List>([])
  const [category2Id, setCategory2Id] = useState<number>()
  const [categoryTwoList, setCategoryTwoList] = useState<category2List>([])
  const [category3Id, setCategory3Id] = useState<number>()
  const [categoryThreeList, setCategoryThreeList] = useState<category3List>([])
  const [attrList, setAttrList] = useState<AttrList>([])
  const [isShow, setIsShow] = useState(false)
  const [showIpt, setShowIpt] = useState(-1)

  // 设置保存修修改的属性对象
  const [attrInfo, setAttrInfo] = useState<AttrItem>({
    attrName: '',
    categoryId: category3Id as number,
    categoryLevel: 3,
    attrValueList: [],
    id: '',
  })

  // 设置动态的属性名称数组
  const [valueList, setValueList] = useState<AttrValueList>([])

  const [form] = Form.useForm()

  // 属性展示列表
  const colData: ColumnsType<AttrItem> = [
    {
      title: '序号',
      dataIndex: 'index',
      width: '5%',
      render: (text, record, index) => {
        return <span>{index}</span>
      }
    },
    {
      title: '商品属性',
      dataIndex: 'attrName',
      width: '10%',
    },
    {
      title: '商品属性名列表',
      dataIndex: 'attrValueList',
      width: '70%',
      render: (text, record, index) => {
        return text.map((item: AttrValueItem) => {
          return <Tag color="magenta" key={item.id}>{item.valueName}</Tag>
        })
      }
    },
    {
      title: '操作',
      dataIndex: 'action',
      render: (text, record: AttrItem) => {
        return (
          <>
            <Button
              style={{ backgroundColor: 'orange', marginRight: '20px', color: 'white' }}
              icon={<EditOutlined />}
              onClick={() => addOrUpDateInfo(record)}
            ></Button>

            <Button
              icon={<DeleteOutlined />}
              type='primary'
              danger
              onClick={() => delAttr(record)}
            ></Button>
          </>
        )
      }
    }
  ]

  // 添加修改属性列表
  const addOrUpDate: ColumnsType<AttrValueItem> = [
    {
      title: '序号',
      dataIndex: 'index',
      width: '10%',
      render: (text, record, index) => {
        return <span>{index + 1}</span>
      }
    },
    {
      title: '属性值列表',
      dataIndex: 'valueName',
      width: '80%',
      render: (text, record, index) => {
        return (
          <>
            {
              showIpt === index
                ?
                <Input
                // defaultValue表示初次渲染时候的数据，
                  defaultValue={text}
                  autoFocus onBlur={() => rulesValue(index)}
                  onChange={(e) => changeValue(e, index)}
                />
                :
                <span onClick={() => setShowIpt(index)} >{text}</span>
            }
          </>
        )
      }
    },
    {
      title: '操作',
      dataIndex: 'action',
      render: (text, record, index) => {
        return <Button
          danger
          type='primary'
          icon={<DeleteOutlined />}
          onClick={() => removeValue(index)}
        ></Button>
      }
    }
  ]


  // 改变input属性名的值
  const changeValue = (e: any, index: number) => {

    // 必须用defaultValue和浅拷贝来实现
    // 浅拷贝数组，里面是对象，对象地址不会变
    // 所以这里修改的时候，虽然状态不会同步更新
    // 但是里面的数值已经改变了，所以在失焦时也可以用
    let arr = [...valueList]
    // let arr = cloneDeep(valueList)

    arr[index].valueName = e.target.value

    // console.log(valueList[index])
    // setValueList(arr);
  }

  // 失去焦点的时候验证属性名的值是否重复，是否为空
  const rulesValue = (index: number) => {
    let arr = [...valueList]
    let valueName = arr[index].valueName
    if (valueName && valueName.trim()) {
      // 如果值不为空，判断数组中是否有和其值一样的对象
      // 需要将自己去除，不然永远为假
      let rules = arr.some((item, index1) => {
        if (index !== index1) {

          return item.valueName === valueName
        }
      })
      if (rules) {
        // 为真表示有重复的值,删除这个对象
        arr.splice(index, 1);
        message.error("有重复的属性名")
      } else {

        message.success('添加属性名成功')
      }


    } else {
      // 如果为空，直接删除当前对象
      arr.splice(index, 1);
      message.error("没有填写有效的值")
    }
    setValueList(arr)
    setShowIpt(-1)
  }

  // 点击属性名的删除按钮
  const removeValue = (index: number) => {
    let arr = [...valueList]
    arr.splice(index, 1)
    setValueList(arr)
  }

  // 1级分类请求函数
  const reqGetCategory1 = async () => {
    try {
      const result = await reqCategory1List()
      // console.log(result)
      setCategoryOneList(result)
      message.success('获取1级分类成功')
    } catch (error) {
      message.error('获取1级分类失败')

    }

  }

  // 2级分类请求函数
  const reqGetCategory2 = async () => {
    try {
      const result = await reqCategory2List(category1Id as number)
      setCategoryTwoList(result)
      message.success('获取2级分类成功')
    } catch (error) {
      message.error('获取2级分类失败')
    }
  }

  // 3级分类请求函数
  const reqGetCategory3 = async () => {
    try {
      const result = await reqCategory3List(category2Id as number)
      setCategoryThreeList(result)

      message.success('获取3级分类成功')
    } catch (error) {
      message.error('获取3级分类失败')
    }
  }

  // 根据3级Id获取商品属性列表
  const GetAttrList = async () => {
    try {
      const result = await reqGetAttrList(category1Id as number, category2Id as number, category3Id as number)
      setAttrList(result)
      message.success('获取商品属性列表成功')
    } catch (error) {
      message.error('获取商品属性列表失败')

    }
  }

  // 根据下拉框设置1级Id 
  const setOneId = (value: number) => {
    setCategory1Id(value)
    setCategory2Id(undefined)
    setCategoryTwoList([])
    setCategory3Id(undefined)
    setCategoryThreeList([])
    setAttrList([])
    form.setFieldsValue({
      select3: '请选择',
      select2: '请选择',
    })
  }

  // 根据下拉框设置2级Id
  const setTwoId = (value: number) => {
    // 设置动态数据的第二个函数是一个异步函数
    // 所以在设置之后马上打印会出现undefined
    // 如果想看，可以在这个状态的生命周期里面去打印
    setCategory2Id(value)
    setCategory3Id(undefined)
    setCategoryThreeList([])
    setAttrList([])
    form.setFieldsValue({
      select3: '请选择',
    })
    // console.log(category2Id)

  }

  // 根据下拉框设置3级Id
  const setThreeId = (value: number) => {
    setCategory3Id(value);
  }

  // 组件挂载后请求1级分类
  useEffect(() => {
    reqGetCategory1();
  }, [])

  // 当1Id改变时获取2级分类
  useEffect(() => {
    if (category1Id) {
      reqGetCategory2()
    }

  }, [category1Id])


  // 当2Id改变时获取3级分类
  useEffect(() => {
    if (category2Id) {
      reqGetCategory3()
    }
  }, [category2Id])

  // 当3Id改变时获取
  useEffect(() => {
    if (category3Id) {
      GetAttrList()
    }
  }, [category3Id])



  // 点击显示添加属性的卡片，如果点击的是添加那么做数据回显
  const addOrUpDateInfo = (obj: AttrItem) => {
    let newObj: AttrItem = {
      attrName: '',
      categoryId: category3Id as number,
      categoryLevel: 3,
      attrValueList: [],
    }

    setIsShow(true)
    if (obj.id) {
      // 有id，数据回显，修改数据
      form.setFieldsValue({
        attrName: obj.attrName
      })
      newObj.attrName = obj.attrName
      newObj.id = obj.id
      setAttrInfo(newObj)
      setValueList(cloneDeep(obj.attrValueList))

    } else {
      // 没有id，新增属性

      form.setFieldsValue({
        attrName: ''
      })
      setAttrInfo(newObj)
      setValueList(newObj.attrValueList)

    }

  }

  // 点击取消按钮
  const cancelShow = () => {
    setIsShow(false);
    setAttrInfo({
      ...attrInfo,
      id: '',
    })
  }


  // changedValues: any, 这个参数显示改变的当前的input元素
  // values: any,   这个参数显示所有input元素
  const changeName = (changedValues: any) => {

    setAttrInfo({
      ...attrInfo,
      attrName: changedValues.attrName
    })
  }

  // 添加属性名对象
  const pushValueList = () => {
    setValueList([
      ...valueList,
      {
        valueName: '',
      }
    ])
    setShowIpt(valueList.length)
  }

  // 添加或更新属性
  const addOrUpDateAttrInfo = async () => {

    // 判断当前attr对象和其他的attr对象是否重名
    const rules = attrList.some(item => {
      // 先把自己提出来，和其他人判断
      if (item.id !== attrInfo.id) {

        return item.attrName === attrInfo.attrName
      }
    })

    if (rules) {
      // 有，表示有属性重名，则不能保存
      message.error('有属性重名')
    } else {
      // 没有，表示没有重名，可以保存

      try {
        let obj = { ...attrInfo }
        obj.attrValueList = valueList
        // 设置set状态的时候因为是异步操作
        // 所以最好别用状态来发请求，而是另外用一个变量来保存数据，然后用这个变量来发送请求

        await reqAddOrUpDate(obj);
        message.success('保存属性名成功')
        setIsShow(false)
        GetAttrList()

      } catch (error) {
        message.error('保存属性名失败')
      }

    }

  }

  // 点击删除属性
  const delAttr = async (obj: AttrItem) => {
    // removeAttr
    try {
      await removeAttr(obj.id as number)
      message.success('删除成功')
      GetAttrList()
    } catch (error) {
      message.error('删除失败')
    }
  }

  return (
    <>

      <Card style={{ margin: '0 20px' }}>
        <Form
          labelCol={{ span: 20 }}
          layout="inline"
          form={form}
        >

          <Form.Item label="一级分类">
            <Select style={{ width: '200px', marginRight: '50px' }}
              onChange={setOneId}
              placeholder='请选择'
              disabled={isShow}
            >
              {
                categoryOneList.map((item: category1Item) => {
                  return <Select.Option value={item.id} key={item.id}>{item.name}</Select.Option>

                })

              }
            </Select>
          </Form.Item>

          <Form.Item label="二级分类" name='select2'>
            <Select style={{ width: '200px', marginRight: '50px' }}
              onChange={setTwoId}
              placeholder='请选择'
              disabled={typeof category1Id !== 'number' || isShow}
            >
              {
                categoryTwoList.map((item: category2Item) => {

                  return <Select.Option value={item.id} key={item.id}>{item.name}</Select.Option>

                })
              }
            </Select>
          </Form.Item>

          <Form.Item label="三级分类" name='select3'>
            <Select style={{ width: '200px' }} onChange={setThreeId}
              placeholder='请选择'
              disabled={typeof category2Id !== 'number' || isShow}
            >
              {
                categoryThreeList.map((item: category3Item) => {
                  return <Select.Option value={item.id} key={item.id} >{item.name}</Select.Option>
                })
              }
            </Select>
          </Form.Item>
        </Form>
      </Card>

      <Card style={{ margin: '20px 20px 0' }}>

        {
          isShow

            ?
            <>
              <Form
                form={form}
                labelCol={{ span: 10 }}
                wrapperCol={{ span: 5 }}
                layout='inline'
                style={{ marginBottom: '20px' }}
                onValuesChange={changeName}
              >
                <FormItem name='attrName' label='属性名'>
                  <Input />
                </FormItem>
              </Form>
              <Button type='primary' icon={<PlusOutlined />}
                style={{ marginRight: '20px' }}
                onClick={pushValueList}
                disabled={attrInfo.attrName === ''}
              >添加属性值</Button>
              <Button onClick={cancelShow}>取消</Button>

              <Table columns={addOrUpDate} dataSource={valueList} rowKey="valueName" pagination={false}></Table>

              <Button type='primary'
                style={{ marginRight: '20px' }}
                disabled={valueList.length < 1}
                onClick={addOrUpDateAttrInfo}
              >保存</Button>
              <Button onClick={cancelShow}>取消</Button>
            </>
            :
            <>
              <Button
                type="primary"
                icon={<PlusOutlined />}
                style={{ marginBottom: '20px' }}
                disabled={typeof category3Id !== 'number'}
                onClick={() => addOrUpDateInfo(attrInfo)}
              >
                添加属性
              </Button>

              <Table columns={colData} dataSource={attrList} rowKey='id' pagination={false}>

              </Table>
            </>

        }
      </Card>





    </>
  )
}
